home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////
- // QCDEMOD.CPP: Quadcode demo program for DOS
- // Written by:
- // Kenneth Van Camp
- // RR #1 Box 1255
- // East Stroudsburg, PA 18301
- // (717)223-8620
- //
- // Functions -
- // main main pgm entry point
- // init_graphics initialize graphics
- // Cursor::Cursor default constructor
- // Cursor::Move move cursor
- // RegionDisplay::Display display region
- // RegionDisplay::Interact user interaction
- // dos_yieldfunc yield function for build
- //
- ///////////////////////////////////////////////////////
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include <time.h>
- #include <graphics.h>
- #include <conio.h>
- #include <iostream.h>
- #include "qc.h"
-
- void init_graphics (void);
- int dos_yieldfunc (int pct_complete);
-
- const char CR = '\015', // carriage return code
- ESC = '\033'; // escape code
-
- int xres, // horiz screen resolution
- yres, // vert screen resolution
- shrink = TRUE, // shrink all qc's for plotting?
- qccolor = 1, // color to paint quadcodes
- xsize, // size of a single-division qc
- ysize,
- xoffs; // offset to center picture on scrn
-
- // class RegionDisplay: A Region class with graphical
- // display and interaction capabilities.
- class RegionDisplay: public Region
- {
- public:
- RegionDisplay // constructor from outline
- (PointListHeader &vertex_list):
- Region (vertex_list) { } // calls base constr.
- void Display (void); // display on graphics screen
- void Interact (void); // graphic interact function
- }; // class RegionDisplay
-
- // struct Cursor: Controls display of crosshair cursor.
- struct Cursor
- {
- int xlen,
- ylen,
- xpos,
- ypos;
- Cursor (void);
- void Move (int xdist, int ydist);
- };
-
- ///////////////////////////////////////////////////////
- // main: Main program entry point
-
- int main (int argc, char **argv)
- {
- if (argc != 1)
- {
- if (argc != 2 || strcmp (argv[1], "-n") != 0)
- {
- cerr << "usage: QCdemo [-n]\n";
- cerr << " where -n specifies no shrinkage\n";
- return 1;
- }
- shrink = FALSE;
- }
-
- const int npts = 37;
- const int ndiv = 128;
- const int reduce = 1;
- Point plist[npts] =
- {
- { 5, 68}, { 28, 68}, { 32, 88}, { 33, 94},
- { 31,110}, { 30,113}, { 35,124}, { 51,125},
- { 63,127}, { 63,119}, { 67,116}, { 59,109},
- { 63,119}, { 63,127}, { 74,126}, { 80,125},
- { 88,112}, { 99,101}, {107, 98}, {113, 96},
- {124, 98}, {122, 94}, {123, 91}, {121, 85},
- {118, 78}, {108, 73}, { 96, 64}, { 85, 58},
- { 81, 50}, { 82, 46}, { 90, 38}, { 83, 25},
- { 72, 21}, { 58, 8}, { 55, 8}, { 54, 40},
- { 5, 40},
- };
- PointListHeader phdr =
- {
- npts, ndiv, plist
- };
-
- // Reduce to proper size
- phdr.ndiv /= reduce;
- int i;
- for (i = 0; i < npts; i++)
- {
- phdr.pointptr[i].i /= reduce;
- phdr.pointptr[i].j /= reduce;
- }
-
- // Set the yield function so user can interrupt.
- SetRegionYieldFunc (dos_yieldfunc);
-
- time_t tstart;
- time (&tstart);
- cout << "Building quadcode region (press Escape to Abort)\n";
-
- // Build the region from a perimeter list
- RegionDisplay reg (phdr);
-
- time_t tend;
- time (&tend);
-
- if (reg.NumQC() == 0)
- {
- cout << "\nREGION BUILD ABORTED!\n";
- return 0;
- }
-
- init_graphics();
-
- // Display the region, then allow user interaction.
- reg.Display();
- reg.Interact();
-
- restorecrtmode();
- cout << "There are " << reg.NumQC() <<
- " quadcodes in the region.\n";
- cout << "Region was built in " <<
- (long)difftime (tend, tstart) << " secs.\n";
-
- return 0;
- } // main
-
- ///////////////////////////////////////////////////////
- // init_graphics: Initialize graphics under TC++.
-
- void init_graphics (void)
- {
- // Initialize graphics
- int driver = DETECT,
- mode,
- errc;
-
- initgraph (&driver, &mode, getenv ("BGIDIR"));
- if ((errc = graphresult()) != grOk)
- {
- cerr << "Graph Error: " << grapherrormsg (errc);
- exit (1);
- }
- xres = getmaxx () + 1;
- yres = getmaxy () + 1;
- int maxcol = getmaxcolor ();
- if (maxcol >= WHITE)
- qccolor = WHITE;
- else if (maxcol >= GREEN)
- qccolor = GREEN;
- } // init_graphics
-
- ///////////////////////////////////////////////////////
- // Cursor::Cursor: Default constructor
-
- Cursor::Cursor (void)
- {
- xpos = xres / 2;
- ypos = yres / 2;
- xlen = xres / 75;
- ylen = yres / 50;
-
- setwritemode (XOR_PUT);
- setcolor (qccolor);
- line (xpos - xlen, ypos, xpos + xlen, ypos);
- line (xpos, ypos - ylen, xpos, ypos + ylen);
- } // Cursor::Cursor
-
- ///////////////////////////////////////////////////////
- // Cursor::Move: Move the cursor a specified distance.
-
- void Cursor::Move (int xdist, int ydist)
- // xdist is the dist to move right (left if negative)
- // ydist is the dist to move down (up if negative)
- {
- // Erase the old cursor
- setwritemode (XOR_PUT);
- line (xpos - xlen, ypos, xpos + xlen, ypos);
- line (xpos, ypos - ylen, xpos, ypos + ylen);
-
- // Update in new position
- xpos += xdist;
- ypos += ydist;
- xpos = max (0, xpos);
- xpos = min (xres - 1, xpos);
- ypos = max (0, ypos);
- ypos = min (yres - 1, ypos);
-
- line (xpos - xlen, ypos, xpos + xlen, ypos);
- line (xpos, ypos - ylen, xpos, ypos + ylen);
- } // Cursor::Move
-
- ///////////////////////////////////////////////////////
- // RegionDisplay::Display: Display region graphically.
-
- void RegionDisplay::Display (void)
- // ndiv is the # of divisions to use on the screen
- {
- setcolor (qccolor);
- setfillstyle (SOLID_FILL, qccolor);
-
- // Find usable display area:
- int ux = (float)xres / 1.5;
- // Calculate size of a single-division quadcode:
- xsize = ux / ndiv;
- ysize = yres / ndiv;
- xoffs = (xres - ux) * 0.5;
-
- QCNode *qcn;
- for (qcn = first_qcnode; qcn; qcn = qcn->next)
- {
- COORD i, j;
- int nq;
- qcn->ToIJ (i, j, nq);
- COORD nqc_div = 1L << nq;
- float qcfact = ndiv / nqc_div;
- int xlen = xsize * qcfact;
- int ylen = ysize * qcfact;
- int x = xoffs + j * xsize * qcfact;
- int y = i * ysize * qcfact;
- if (shrink)
- {
- x++;
- y++;
- xlen -= 2;
- ylen -= 2;
- }
- bar (x, y, x + xlen, y + ylen);
- } // for qcn
-
- } // RegionDisplay::Display
-
- ///////////////////////////////////////////////////////
- // RegionDisplay::Interact: User interact with region.
-
- void RegionDisplay::Interact (void)
- {
- Cursor csr;
-
- setcolor (qccolor);
- setfillstyle (SOLID_FILL, qccolor);
- int nquits = MaxQuits();
- int xbox = xres / 75;
- int ybox = yres / 50;
- int hispeed = yres / 50;
- int speed = hispeed;
-
- while(1)
- {
- // Update status box
- int i = csr.ypos / ysize;
- int j = (csr.xpos - xoffs) / xsize;
- // Only check if within region limits
- if (i >= 0 && i < ndiv && j >= 0 && j < ndiv)
- {
- QuadCode qc (i, j, nquits);
- setwritemode (COPY_PUT);
- if (InRegion (qc))
- {
- // In region - draw solid status box
- bar (0, 0, xbox, ybox);
- }
- else
- {
- // Out of region - draw empty status box
- setfillstyle (EMPTY_FILL, qccolor);
- bar (0, 0, xbox, ybox);
- setfillstyle (SOLID_FILL, qccolor);
- rectangle (0, 0, xbox, ybox);
- }
- }
- else
- {
- // Outside region limits - draw empty status box
- setfillstyle (EMPTY_FILL, qccolor);
- bar (0, 0, xbox, ybox);
- setfillstyle (SOLID_FILL, qccolor);
- rectangle (0, 0, xbox, ybox);
- }
-
- // Get last key in kybd buffer (no type-ahead)
- int ch;
- do
- {
- ch = getch();
- if (ch == 0)
- // Extended key codes (arrow keys)
- ch = getch();
- } while (kbhit());
-
- switch (ch)
- {
- case 's': // toggle speed
- case 'S':
- if (speed == hispeed)
- speed = 1;
- else
- speed = hispeed;
- break;
-
- case 'H': // up arrow
- csr.Move (0, -speed);
- break;
-
- case 'P': // down arrow
- csr.Move (0, speed);
- break;
-
- case 'K': // left arrow
- csr.Move (-speed, 0);
- break;
-
- case 'M': // right arrow
- csr.Move (speed, 0);
- break;
-
- case '\033': // escape
- return;
-
- default:
- putchar ('\a');
- } // switch
-
- } // while
- } // RegionDisplay::Interact
-
- ///////////////////////////////////////////////////////
- // dos_yieldfunc: A function that is called periodically
- // during region building to yield control to the user
- // or another application. Under DOS, it just lets the
- // user abort the build with an Escape. It returns TRUE
- // if the user aborts, or FALSE otherwise.
-
- int dos_yieldfunc (int pct_complete)
- // pct_complete is the percent of region built
- {
- printf ("%c%3d%% Complete", CR, pct_complete);
- if (kbhit())
- {
- if (getch() == ESC)
- return (TRUE);
- }
- return (FALSE);
- } // dos_yieldfunc
-